package com.jiangjiang.eshop.wms.stock;

import com.jiangjiang.eshop.wms.domain.WmsGoodsAllocationStock;
import com.jiangjiang.eshop.wms.domain.WmsGoodsAllocationStockDetail;
import com.jiangjiang.eshop.wms.domain.WmsGoodsStock;
import com.jiangjiang.eshop.wms.dto.GoodsAllocationStockDetailDTO;
import com.jiangjiang.eshop.wms.dto.PurchaseInputOrderDTO;
import com.jiangjiang.eshop.wms.dto.PurchaseInputOrderItemDTO;
import com.jiangjiang.eshop.wms.service.WmsGoodsAllocationService;
import com.jiangjiang.eshop.wms.service.WmsGoodsAllocationStockDetailService;
import com.jiangjiang.eshop.wms.service.WmsGoodsAllocationStockService;
import com.jiangjiang.eshop.wms.service.WmsGoodsStockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author Jianghaowen
 * @Date 2021/9/14
 * @Description: TODO
 * @Version V1.0
 **/
@Component
@Scope("prototype")
public class PurchaseInputWmsStockUpdater extends AbstractWmsStockUpdater {

    private PurchaseInputOrderDTO purchaseInputOrder;

    @Autowired
    private WmsGoodsStockService goodsStockService;
    @Autowired
    private WmsGoodsAllocationStockService goodsAllocationStockService;
    @Autowired
    private WmsGoodsAllocationStockDetailService goodsAllocationStockDetailService;

    @Override
    protected void updateGoodsStock() throws Exception {

        Set<Long> goodsSkuIds = purchaseInputOrder.getItems()
                .stream()
                .map(PurchaseInputOrderItemDTO::getGoodsSkuId)
                .collect(Collectors.toSet());

        Map<Long, WmsGoodsStock> goodsStockMap = goodsStockService.queryBySkuIds(goodsSkuIds)
                .stream()
                .collect(Collectors.toMap(WmsGoodsStock::getGoodsSkuId, Function.identity()));

        List<WmsGoodsStock> stocks = purchaseInputOrder.getItems().stream().map(item -> {
            WmsGoodsStock wmsGoodsStock = goodsStockMap.get(item.getGoodsSkuId());
            if (Objects.isNull(wmsGoodsStock)) {
                wmsGoodsStock = new WmsGoodsStock();
                wmsGoodsStock.setGoodsSkuId(item.getGoodsSkuId());
                wmsGoodsStock.setAvailableStockQuantity(item.getPurchaseCount());
                wmsGoodsStock.setLockedStockQuantity(0L);
                wmsGoodsStock.setOutputStockQuantity(0L);
            } else {
                wmsGoodsStock.setAvailableStockQuantity(wmsGoodsStock.getAvailableStockQuantity() + item.getPurchaseCount());
            }
            return wmsGoodsStock;
        }).collect(Collectors.toList());

        goodsStockService.saveOrUpdateBatch(stocks);
    }

    @Override
    protected void updateGoodsAllocationStock() {
        for (PurchaseInputOrderItemDTO item : purchaseInputOrder.getItems()) {
            Map<Long, WmsGoodsAllocationStock> goodsAllocationStockMap = goodsAllocationStockService.queryBySkuId(item.getGoodsSkuId())
                    .stream()
                    .collect(Collectors.toMap(WmsGoodsAllocationStock::getGoodsAllocationId, Function.identity()));

            List<WmsGoodsAllocationStock> allocationStocks = item.getPutOnItems().stream().map(putOnItem -> {
                WmsGoodsAllocationStock stock = goodsAllocationStockMap.get(putOnItem.getGoodsAllocationId());
                if (Objects.isNull(stock)) {
                    stock = new WmsGoodsAllocationStock();
                    stock.setLockedStockQuantity(0L);
                    stock.setOutputStockQuantity(0L);
                    stock.setGoodsSkuId(putOnItem.getGoodsSkuId());
                    stock.setGoodsAllocationId(putOnItem.getGoodsAllocationId());
                    stock.setAvailableStockQuantity(putOnItem.getPutOnShelvesCount());

                } else {
                    stock.setAvailableStockQuantity(stock.getAvailableStockQuantity() + putOnItem.getPutOnShelvesCount());
                }
                return stock;

            }).collect(Collectors.toList());
            // 批量保存
            goodsAllocationStockService.saveOrUpdateBatch(allocationStocks);
        }
    }

    @Override
    protected void updateGoodsAllocationStockDetail() throws Exception {

        for (PurchaseInputOrderItemDTO item : purchaseInputOrder.getItems()) {
            List<WmsGoodsAllocationStockDetail> details = item.getPutOnItems().stream().map(putOnItem -> {
                WmsGoodsAllocationStockDetail stockDetail = new WmsGoodsAllocationStockDetail();
                stockDetail.setGoodsAllocationId(putOnItem.getGoodsAllocationId());
                stockDetail.setGoodsSkuId(putOnItem.getGoodsSkuId());
                stockDetail.setPutOnQuantity(putOnItem.getPutOnShelvesCount());
                stockDetail.setPutOnTime(putOnItem.getGmtCreate());
                stockDetail.setCurrentStockQuantity(stockDetail.getPutOnQuantity());
                stockDetail.setLockedStockQuantity(0L);
                return stockDetail;
            }).collect(Collectors.toList());

            goodsAllocationStockDetailService.saveBatch(details);
            item.setStockDetails(goodsAllocationStockDetailService.convertEntities2DTOList(details));
        }
    }

    @Override
    public void setParameter(Object parameter) {
        this.purchaseInputOrder = (PurchaseInputOrderDTO) parameter;
    }
}
